package aliyun.cx.admin.controller;

import aliyun.cx.admin.util.ConfigUtil;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.ThreadMXBean;
import java.text.DecimalFormat;

/**
 * 系统监控控制器
 */
@RestController
@RequestMapping("/api/system/monitor")
@CrossOrigin(origins = "*", maxAge = 3600)
public class SystemMonitorController {

    private final ConfigUtil configUtil;
    
    public SystemMonitorController(ConfigUtil configUtil) {
        this.configUtil = configUtil;
    }

    /**
     * 获取当前系统监控数据
     */
    @GetMapping("/current")
    public Map<String, Object> getSystemMonitor() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 检查系统监控是否启用
            if (!configUtil.isSystemMonitorEnabled()) {
                result.put("code", 403);
                result.put("message", "系统监控功能已禁用");
                return result;
            }
            
            Map<String, Object> monitorData = new HashMap<>();
            
            // 获取内存信息
            MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
            long totalMemory = memoryBean.getHeapMemoryUsage().getMax();
            long usedMemory = memoryBean.getHeapMemoryUsage().getUsed();
            long freeMemory = totalMemory - usedMemory;
            
            DecimalFormat df = new DecimalFormat("#.##");
            double memoryUsagePercent = (double) usedMemory / totalMemory * 100;
            
            Map<String, Object> memory = new HashMap<>();
            memory.put("total", formatBytes(totalMemory));
            memory.put("used", formatBytes(usedMemory));
            memory.put("free", formatBytes(freeMemory));
            memory.put("usagePercent", Double.parseDouble(df.format(memoryUsagePercent)));
            monitorData.put("memory", memory);
            
            // 获取CPU信息
            OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
            Map<String, Object> cpu = new HashMap<>();
            cpu.put("cores", osBean.getAvailableProcessors());
            cpu.put("loadAverage", Double.parseDouble(df.format(osBean.getSystemLoadAverage())));
            monitorData.put("cpu", cpu);
            
            // 获取线程信息
            ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
            Map<String, Object> thread = new HashMap<>();
            thread.put("total", threadBean.getThreadCount());
            thread.put("peak", threadBean.getPeakThreadCount());
            thread.put("daemon", threadBean.getDaemonThreadCount());
            monitorData.put("thread", thread);
            
            // 获取系统信息
            Map<String, Object> system = new HashMap<>();
            system.put("osName", osBean.getName());
            system.put("osVersion", osBean.getVersion());
            system.put("osArch", osBean.getArch());
            system.put("javaVersion", System.getProperty("java.version"));
            system.put("javaVendor", System.getProperty("java.vendor"));
            monitorData.put("system", system);
            
            // 获取JVM信息
            Runtime runtime = Runtime.getRuntime();
            Map<String, Object> jvm = new HashMap<>();
            
            // JVM运行时间和启动信息
            jvm.put("uptime", formatUptime(ManagementFactory.getRuntimeMXBean().getUptime()));
            jvm.put("startTime", ManagementFactory.getRuntimeMXBean().getStartTime());
            
            // JVM版本信息
            jvm.put("version", System.getProperty("java.version"));
            jvm.put("vendor", System.getProperty("java.vendor"));
            jvm.put("home", System.getProperty("java.home"));
            
            // JVM内存信息（基于Runtime）
            long jvmMaxMemory = runtime.maxMemory();
            long jvmTotalMemory = runtime.totalMemory();
            long jvmFreeMemory = runtime.freeMemory();
            long jvmUsedMemory = jvmTotalMemory - jvmFreeMemory;
            
            Map<String, Object> jvmMemory = new HashMap<>();
            jvmMemory.put("max", formatBytes(jvmMaxMemory));
            jvmMemory.put("total", formatBytes(jvmTotalMemory));
            jvmMemory.put("used", formatBytes(jvmUsedMemory));
            jvmMemory.put("free", formatBytes(jvmFreeMemory));
            jvmMemory.put("usagePercent", Double.parseDouble(df.format((double) jvmUsedMemory / jvmTotalMemory * 100)));
            jvm.put("memory", jvmMemory);
            
            // JVM处理器信息
            jvm.put("availableProcessors", runtime.availableProcessors());
            
            // JVM系统属性
            Map<String, Object> properties = new HashMap<>();
            properties.put("javaHome", System.getProperty("java.home"));
            properties.put("javaClassPath", System.getProperty("java.class.path").length() + " characters");
            properties.put("userDir", System.getProperty("user.dir"));
            properties.put("tempDir", System.getProperty("java.io.tmpdir"));
            jvm.put("properties", properties);
            
            monitorData.put("jvm", jvm);
            
            result.put("code", 200);
            result.put("message", "获取系统监控数据成功");
            result.put("data", monitorData);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "获取系统监控数据失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 格式化字节数
     */
    private String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + " B";
        int exp = (int) (Math.log(bytes) / Math.log(1024));
        String pre = "KMGTPE".charAt(exp-1) + "";
        return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);
    }
    
    /**
     * 格式化运行时间
     */
    private String formatUptime(long uptime) {
        long days = uptime / (24 * 60 * 60 * 1000);
        long hours = (uptime % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000);
        long minutes = (uptime % (60 * 60 * 1000)) / (60 * 1000);
        long seconds = (uptime % (60 * 1000)) / 1000;
        
        if (days > 0) {
            return days + "天 " + hours + "小时 " + minutes + "分钟 " + seconds + "秒";
        } else if (hours > 0) {
            return hours + "小时 " + minutes + "分钟 " + seconds + "秒";
        } else if (minutes > 0) {
            return minutes + "分钟 " + seconds + "秒";
        } else {
            return seconds + "秒";
        }
    }
}
